/****************************************************************************
** @brief concrete state subcalsses
****************************************************************************/

#include "startingStatus.h"
#include "chargingStatus.h"
#include "finishStatus.h"

#include "../oiovMain.h"
#include "../oiovCallback.h"
#include "../controllerMain.h"

#include "../../controller/controller_can.h"
#include "../../iov/feestrategy-lib/inc/app_fee_strategy.h"

#include <QDebug>
#define STARTSTATE_DEBUG

Status *StartingStatus::instance_ = nullptr;

StartingStatus::StartingStatus() : Status()
{
    state_ = Status::kStarting;
}

StartingStatus::~StartingStatus()
{

}

Status *StartingStatus::instance()
{
    if (nullptr == instance_) {
        instance_ = new StartingStatus();
    }
    return instance_;
}

void StartingStatus::Process(Gun *g)
{
    time_t _time;

    time(&_time);

    int start_timeout;
    unsigned char no = g->gun_number();

    if ((CONGUNNOA != no) && (CONGUNNOB != no)) {
        return;
    }

    no = no - CONGUNNOA;

#if defined(STARTSTATE_DEBUG)
    static int count = 0;
    if (++count >= 5 * 1000 / 100) {
        count = 0;
        qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting state... ( start timeout: " << g->start_timeout() << ")";
    }
#endif

    switch (ControllerParserMain::con_telecommand[no].work_state) {
    case WAIT_STATE:
        if (g->start_timeout() <= 0) {
            ChangeState(g, FinishStatus::instance()); //切换到充电完成未拔枪

#if defined(STARTSTATE_DEBUG)
            qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting -> finish";
#endif

            //充电结束，不要上报充电中的属性数据了
            OiovReqMain::ClearChargingProperty(no);

            //设备状态 -> 充电结束未拔枪
            OiovCallback::ops_property_charge_data[no].status = OiovCallback::OPS_CHARGINGPILE_STATE_IDLE;
            //向平台发送设备状态事件
            OiovReqMain::SetDeviceStatusEvent(no);

            //上报交易记录
            if (OiovCallback::OPS_TRANSACTION_TYPE_APP == OiovCallback::ops_event_bill[no].transaction_type || OiovCallback::OPS_TRANSACTION_TYPE_ONCARD == OiovCallback::ops_event_bill[no].transaction_type) {
                OiovReqMain::SetStopChargeEvent(no);
            }
        } else {
            start_timeout = g->start_timeout();
            g->set_start_timeout(start_timeout - 1);
        }

        if (ControllerParserMain::StopChargingService(no)) {
            ControllerParserMain::ClearStopChargingService(no); //清除标志位

            ChangeState(g, FinishStatus::instance()); //切换到充电完成未拔枪

#if defined(STARTSTATE_DEBUG)
            qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting -> finish";
#endif

            //充电结束，不要上报充电中的属性数据了
            OiovReqMain::ClearChargingProperty(no);

            //设备状态 -> 充电结束未拔枪
            OiovCallback::ops_property_charge_data[no].status = OiovCallback::OPS_CHARGINGPILE_STATE_IDLE;
            //向平台发送设备状态事件
            OiovReqMain::SetDeviceStatusEvent(no);

            //data - 填充交易记录
            switch (ControllerParserMain::con_charg_stop_result[no].result_code) {
            case 0x02:
                switch (ControllerParserMain::con_charg_stop_result[no].fault_code_one) {
                case 0x01:
                    OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_ABORT_CHARGING_CODE_72; //急停故障
                    break;
                case 0x04:
                    OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_ABORT_CHARGING_CODE_71; //绝缘模块故障
                    break;
                default:
                    break;
                }
                break;
            case 0x05:
                if (0x01 == ControllerParserMain::con_charg_stop_result[no].con_bms_fault_code.bms_fault_code_out_link_overtemp) {
                    OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_ABORT_CHARGING_CODE_74; //输出连接器过温故障
                }
                break;
            default:
                break;
            }
            //上报交易记录
            if (OiovCallback::OPS_TRANSACTION_TYPE_APP == OiovCallback::ops_event_bill[no].transaction_type || OiovCallback::OPS_TRANSACTION_TYPE_ONCARD == OiovCallback::ops_event_bill[no].transaction_type) {
                OiovReqMain::SetStopChargeEvent(no);
            }
        }
        break;
    case CONF_STATE:
        if (g->start_timeout() <= 0) {
            ChangeState(g, FinishStatus::instance()); //切换到充电完成未拔枪

#if defined(STARTSTATE_DEBUG)
            qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting -> finish";
#endif

            //充电结束，不要上报充电中的属性数据了
            OiovReqMain::ClearChargingProperty(no);

            //设备状态 -> 充电结束未拔枪
            OiovCallback::ops_property_charge_data[no].status = OiovCallback::OPS_CHARGINGPILE_STATE_IDLE;
            //向平台发送设备状态事件
            OiovReqMain::SetDeviceStatusEvent(no);

            //上报交易记录
            if (OiovCallback::OPS_TRANSACTION_TYPE_APP == OiovCallback::ops_event_bill[no].transaction_type || OiovCallback::OPS_TRANSACTION_TYPE_ONCARD == OiovCallback::ops_event_bill[no].transaction_type) {
                OiovReqMain::SetStopChargeEvent(no);
            }
        } else {
            start_timeout = g->start_timeout();
            g->set_start_timeout(start_timeout - 1);
        }

        if (ControllerParserMain::StopChargingService(no)) {
            ControllerParserMain::ClearStopChargingService(no); //清除标志位

            ChangeState(g, FinishStatus::instance()); //切换到充电完成未拔枪

#if defined(STARTSTATE_DEBUG)
            qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting -> finish";
#endif

            //充电结束，不要上报充电中的属性数据了
            OiovReqMain::ClearChargingProperty(no);

            //设备状态 -> 充电结束未拔枪
            OiovCallback::ops_property_charge_data[no].status = OiovCallback::OPS_CHARGINGPILE_STATE_IDLE;
            //向平台发送设备状态事件
            OiovReqMain::SetDeviceStatusEvent(no);

            //data - 填充交易记录
            switch (ControllerParserMain::con_charg_stop_result[no].result_code) {
            case 0x02:
                switch (ControllerParserMain::con_charg_stop_result[no].fault_code_one) {
                case 0x01:
                    OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_ABORT_CHARGING_CODE_72; //急停故障
                    break;
                case 0x04:
                    OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_ABORT_CHARGING_CODE_71; //绝缘模块故障
                    break;
                default:
                    break;
                }
                break;
            case 0x05:
                if (0x01 == ControllerParserMain::con_charg_stop_result[no].con_bms_fault_code.bms_fault_code_out_link_overtemp) {
                    OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_ABORT_CHARGING_CODE_74; //输出连接器过温故障
                }
                break;
            default:
                break;
            }
            //上报交易记录
            if (OiovCallback::OPS_TRANSACTION_TYPE_APP == OiovCallback::ops_event_bill[no].transaction_type || OiovCallback::OPS_TRANSACTION_TYPE_ONCARD == OiovCallback::ops_event_bill[no].transaction_type) {
                OiovReqMain::SetStopChargeEvent(no);
            }
        }
        break;
    case CHARGING_STATE:
        ChangeState(g, ChargingStatus::instance()); //切换到充电中

#if defined(STARTSTATE_DEBUG)
        qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting -> charging ( start elect:" << ControllerParserMain::con_telemetry[no].elect * 10 << ")";
#endif

        g->set_charge_elect(ControllerParserMain::con_telemetry[no].elect * 10); //电量初始化
        fi_init((enum fee_number)no, _time, g->charge_elect()); //充电订单初始化
        break;
    case FULL_STATE:
        break;
    case WARRING_STATE:
        break;
    case FAULT_STATE:
        ChangeState(g, FinishStatus::instance()); //切换到充电完成未拔枪

#if defined(STARTSTATE_DEBUG)
        qDebug() << "[CHARGE]->" << (no ? "No.b" : "No.a") << "starting -> finish";
#endif

        //充电结束，不要上报充电中的属性数据了
        OiovReqMain::ClearChargingProperty(no);

        //设备状态 -> 充电结束未拔枪
        OiovCallback::ops_property_charge_data[no].status = OiovCallback::OPS_CHARGINGPILE_STATE_IDLE;
        //向平台发送设备状态事件
        OiovReqMain::SetDeviceStatusEvent(no);

        //data - 填充交易记录
        switch (ControllerParserMain::con_charg_stop_result[no].result_code) {
        case 0x02:
            switch (ControllerParserMain::con_charg_stop_result[no].fault_code_one) {
            case 0x01:
                OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_START_CHARGING_FAILED_CODE_50; //急停故障
                break;
            case 0x04:
                OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_START_CHARGING_FAILED_CODE_4F; //绝缘模块故障
                break;
            default:
                break;
            }
            break;
        case 0x05:
            if (0x01 == ControllerParserMain::con_charg_stop_result[no].con_bms_fault_code.bms_fault_code_out_link_overtemp) {
                OiovCallback::ops_event_bill[no].stop_reason = OiovCallback::DEV_START_CHARGING_FAILED_CODE_53; //输出连接器过温故障
            }
            break;
        default:
            break;
        }
        //上报交易记录
        if (OiovCallback::OPS_TRANSACTION_TYPE_APP == OiovCallback::ops_event_bill[no].transaction_type || OiovCallback::OPS_TRANSACTION_TYPE_ONCARD == OiovCallback::ops_event_bill[no].transaction_type) {
            OiovReqMain::SetStopChargeEvent(no);
        }
        break;
    default:
        break;
    }
}
